import {Injectable} from '@angular/core';
import {CommonTool} from '../common.tool';
import {ArrayConfig, FormInfoModel} from '../form-info/form-info.model';

/**
 * 列表业务逻辑处理类
 * 版本：1.0.0
 */
@Injectable({
  providedIn: 'root'
})
export class TableFindModel {
  static COMMON_TYPE = {
    table: {
      TEXT: 'TEXT', // 显示文本 list-find,table-find
      CHECKBOX: 'CHECKBOX', // 多选框 list-find,table-find
      OPERATE: 'OPERATE', // 操作 list-find,table-find
      RADIO: 'RADIO', // 单选 list-find,table-find
      IMAGE: 'image', // 图片 list-find
      TITLE: 'title', // 标题 list-find
      DESCRIPTION: 'description', // 标题 list-find
      INDEX: 'INDEX', // 序号(前端生成的序号) table-find
      FILE_FOLDER_ICON: 'FILE_FOLDER_ICON', // 文件图标 table-find
      PROGRESS: 'PROGRESS', // 进度条 table-find
      DICT_DESC: 'DICT_DESC', // 字典转换 table-find
      JUMP: 'JUMP', // 跳转
    },
    button: {
      BUTTON: 'BUTTON', // 按钮 list-find
      MIDDLING: 'MIDDLING' // 中等的 table-find
    },
    progress: {
      TEXT: 'TEXT',
      PROGRESS: 'PROGRESS'
    }
  };
  dataModels = [{
    data: {}, // 数据对象
    selected: false // 是否选中
  }];
  config: Config;
  formInfo = {};
  sortDataModels = [];
  selectedAll = false;
  public formInfoModel = new FormInfoModel();

  constructor() {
    this.config = new Config();
    this.dataModels = [];
    this.formInfo = {};
  }

  /**
   * 设置配置
   * 参数 config 配置
   */
  setConfig(config) {
    this.config.finds = config.finds;
    this.config.tables = config.tables;
    this.config.buttons = config.buttons;
    this.config.paging = config.paging ? config.paging : {
      current: 1, // 默认显示第几页
      size: 10, // 默认每页多少条数据
      total: 0, // 总数
      limits: [10, 30, 50, 100, 200] // 每页多少数据的可选参数
    };
    this.config.initDataFun = config.initDataFun;
    this.config.sort = CommonTool.notNull(config.sort) ? config.sort : {field: '', rule: ''};
    this.config.frontSort = CommonTool.notNull(config.frontSort) ? config.frontSort : true;
    this.config.frontPaging = CommonTool.notNull(config.frontPaging) ? config.frontPaging : true;
    this.config.openPaging = CommonTool.notNull(config.openPaging) ? config.openPaging : true;
    this.config.openTable = CommonTool.notNull(config.openTable) ? config.openTable : true;
    this.config.openFind = CommonTool.notNull(config.openFind) ? config.openFind : true;
    this.config.openLabel = CommonTool.notNull(config.openLabel) ? config.openLabel : true;
    this.config.breadcrumb = CommonTool.notNull(config.breadcrumb) ? config.breadcrumb : [];
    this.config.openButton = CommonTool.notNull(config.openButton) ? config.openButton : true;
    // 按钮初始化
    if (CommonTool.notNull(this.config.buttons)) {
      this.config.buttons.forEach(button => {
        if (CommonTool.notNull(button.initFun)) {
          button.initFun(this);
        }
      });
    }
    this.formInfoModel.formConfig.styleClass = 'query-form';
    this.formInfoModel.formConfig.components = this.config.finds;
    const that = this;
    this.formInfoModel.formConfig.components.push({
      name: '搜索',
      field: 'search',
      button: {
        icon: 'search',
        confirmFun(formInfo, component) {
          that.config.paging.current = 1;
          if (that.config.searchFun) {
            that.config.searchFun(formInfo, component);
          } else {
            that.getData(formInfo, null);
          }
        }
      }
    });
  }

  /**
   * 初始化配置并加载数据
   * config 传入的config
   */
  initConfig(config: Config) {
    this.setConfig(config);
    this.getData(this.formInfo, {current: this.config.paging.current, size: this.config.paging.size});
  }

  /**
   * 设置dataModels
   * 参数 dataModels 数据集合
   * 参数 paging 分页信息，total：总数，size：每页总大小
   */
  setDataModels(dataModels, paging) {
    if (CommonTool.notNull(dataModels)) {
      this.dataModels = dataModels;
    } else {
      this.dataModels = [];
    }
    if (CommonTool.notNull(paging)) {
      if (CommonTool.notNull(paging.total)) {
        this.config.paging.total = paging.total;
      }
      if (CommonTool.notNull(paging.size)) {
        this.config.paging.size = paging.size;
      }
    }
  }

  /**
   * 初始化数据
   * 参数 dataModels 数据集合
   */
  initDataModels(dataModels, paging) {
    this.setDataModels(dataModels, paging);
    this.getData(this.formInfo, {current: this.config.paging.current, size: this.config.paging.size});
  }

  /**
   * 初始化查询条件
   */
  setFormInfo(formInfo) {
    if (CommonTool.notNull(formInfo)) {
      this.formInfo = formInfo;
    } else {
      this.formInfo = {};
    }
  }

  /**
   * 全局初始化
   * 参数 config 配置,不能为空
   * 参数 dataModels 表格数据
   * 参数 formInfo 提交数据
   */
  initAll(config, dataModels, formInfo) {
    if (CommonTool.notNull(config)) {
      this.setConfig(config);
    }
    this.setDataModels(dataModels, null);
    this.setFormInfo(formInfo);
    this.getData(this.formInfo, {current: this.config.paging.current, size: this.config.paging.size});
  }

  /**
   * 获取数据
   * 参数 data 查询条件
   * 参数 page 分页参数
   * current 第几页
   * size 每页多少条
   * 参数 sortObj 分页对象
   * field 排序字段
   * sort 排序规则
   */
  getData(data, page) {
    this.selectedAll = false;
    const that = this;
    if (CommonTool.notNull(data)) {
      this.formInfo = data;
    }
    if (CommonTool.notNull(page)) {
      this.config.paging.current = page.current;
      this.config.paging.size = page.size;
    }
    if (CommonTool.notNull(this.config.initDataFun)) {
      const sortPage = {
        sortField: this.config.sort.field,
        sortRule: this.config.sort.rule,
        current: this.config.paging.current,
        size: this.config.paging.size
      };
      this.config.initDataFun(this.formInfo, sortPage, (dataModels, paging) => {
        this.dataModels = dataModels;
        if (CommonTool.notNull(paging)) {
          if (CommonTool.notNull(paging.total)) {
            that.config.paging.total = paging.total;
          }
          if (CommonTool.notNull(paging.size)) {
            that.config.paging.size = paging.size;
          }
        }
        this.dataHandle();
      }, this);
    } else {
      this.dataHandle();
    }
  }

  /**
   * 数据处理
   */
  dataHandle() {
    // 前端分页初始化数据
    if (this.config.frontSort) {
      this.sortDataModels = [];
      this.dataModels.forEach((dataModel) => {
        this.sortDataModels.push(dataModel);
      });
    }
    // 前端排序
    if (this.config.frontSort) {
      this.sort(this.config.sort.field, this.config.sort.rule);
    }
    // 初始化选项
    this.config.tables.forEach(table => {
      if (CommonTool.notNull(table.initOptionFun)) {
        table.initOptionFun(this);
      }
    });
    this.dataModels.forEach(data => {
      // 表格初始化
      if (CommonTool.notNull(this.config.tables)) {
        this.config.tables.forEach(table => {
          if (CommonTool.notNull(table.initFun)) {
            table.initFun(data, this);
          }
          if (CommonTool.notNull(table.operates)) {
            table.operates.forEach(operate => {
              if (CommonTool.notNull(operate.initFun)) {
                operate.initFun(data, table, this);
              }
            });
          }
        });
      }
    });
  }

  /**
   * 单选
   */
  singleSelect(data) {
    this.dataModels.forEach((ref) => {
      ref.selected = false;
    });
    data.selected = true;
  }

  /**
   * 选择
   * 参数: data 数据对象
   * 参数: selected 是否选中
   */
  check(selected, data): void {
    data.selected = selected;
    let index = 0;
    this.dataModels.forEach((ref) => {
      if (ref.selected) {
        index++;
      }
    });
    this.selectedAll = index === this.dataModels.length;
  }

  /**
   * 全选
   * 参数: selectedAll 是否选中
   */
  checkAll(selectedAll) {
    this.selectedAll = selectedAll;
    if (this.selectedAll) {
      this.dataModels.forEach((ref) => {
        ref.selected = true;
      });
    } else {
      this.dataModels.forEach((ref) => {
        ref.selected = false;
      });
    }
  }

  /**
   * 排序
   * 参数: field 排序字段
   * 参数: sort 排序规则，asc:升序，desc:降序，null:不排序
   */
  sort(field, sort) {
    // 前端排序
    if (this.config.frontSort) {
      const dataArray = [];
      this.dataModels.forEach((data) => {
        dataArray.push(data);
      });
      dataArray.sort((ele1, ele2) => {
        if (sort === 'ascend') { // 升序
          if (typeof ele1.data[field] === 'string') {
            return ele1.data[field].localeCompare(ele2.data[field]);
          } else if (typeof ele1.data[field] === 'number') {
            if (ele1.data[field] === ele2.data[field]) {
              return 0;
            } else if (ele1.data[field] < ele2.data[field]) {
              return -1;
            } else {
              return 1;
            }
          }
        } else if (sort === 'descend') {// 降序
          if (typeof ele1.data[field] === 'string') {
            return ele2.data[field].localeCompare(ele1.data[field]);
          } else if (typeof ele1.data[field] === 'number') {
            if (ele1.data[field] === ele2.data[field]) {
              return 0;
            } else if (ele1.data[field] > ele2.data[field]) {
              return -1;
            } else {
              return 1;
            }
          }
        } else {
          if (CommonTool.notNull(this.sortDataModels)) {
            this.dataModels = this.sortDataModels;
          }
        }
      });
      this.dataModels = dataArray;
    } else {
      this.config.sort.field = field;
      this.config.sort.rule = sort;
      // 后端排序
      this.getData(this.formInfo, {current: this.config.paging.current, size: this.config.paging.size});
    }
  }

  /**
   * 分页
   * 参数 current 当前页
   * 参数 size 每页多少条
   */
  paging(current, size) {
    if (CommonTool.notNull(current)) {
      this.config.paging.current = current;
    }
    if (CommonTool.notNull(size)) {
      this.config.paging.size = size;
    }
    this.getData(this.formInfo, {current: this.config.paging.current, size: this.config.paging.size});
  }

  /**
   * 获取选中的数组
   */
  getSelectedArray() {
    const array = [];
    this.dataModels.forEach(dataModel => {
      if (dataModel.selected) {
        array.push(dataModel);
      }
    });
    return array;
  }

  /**
   * 获取选中的第一条
   */
  getSelected() {
    const array = this.getSelectedArray();
    if (CommonTool.notNull(array)) {
      return array[0];
    } else {
      return null;
    }
  }

}

class TableConfig {
  public name: string; // 表头名称
  public field: string; // 数据的字段
  public type: string; // 类型
  public tdStyle?: any; // 表格样式
  public thStyle?: any; // 表格头部样式
  public isSort?: boolean; // 是否开启排序
  public sort?: string; // 默认排序，ascend:升序,descend:降序,null:不排序
  public multiple?: boolean; // 多选，单选
  public isFilter?: boolean; // 过滤
  public options?: Array<any>; // 选择项,字典数据
  public dictType?: string; // 字典类型
  public initOptionFun?: any; // 初始化选项，formInfo：提交form对象,that：当前对象
  public initFun?: any; // dataModel：初始化的数据，that:当前对象
  public confirmFun?: any; // 当前数据，table:配置，当前对象
  public operates?: Array<Operates>; // 操作
}

class Operates {
  public name?: string; // 操作名称
  public bAuthority?: string; // 权限
  public field?: string; // 字段
  public confirmFun?: any; // 当前数据，table:配置，当前对象
  public initFun?: any;  // dataModel：初始化的数据，table:配置，that:当前对象
}

class ButtonConfig {
  public name: string; // 名称
  public type: string; // 类型
  public bAuthority?: string; // 权限
  public icon?: string; // 图标
  public field?: string; // 字段
  public hidden?: boolean; // 隐藏
  public confirmFun?: any;  // 初始化回调，formInfo：提交数据对象，that：当前对象
  public initFun?: any; // 初始化回调，dataModel：数据对象，that：当前对象
  public disabledFun?: any; // 初始化回调，formInfo：提交数据对象，that：当前对象
}

class PagingConfig {
  public current: number; // 默认显示第几页
  public size: number; // 默认每页多少条数据
  public total: number; // 总数
  public limits: Array<number> = [10, 20, 30, 40, 50]; // 每页多少数据的可选参数
}

class SortConfig {
  public field: string; // 排序字段
  public rule: string; // 排序规则
}

class BreadcrumbConfig {
  public labels: Array<{ name: string, data: any }>; // 面包屑
  breadcrumbFun?: any; // 面包屑点击事件,label:当前对象,i:labels下标,that：当前对象
}

class Config {
  public finds: Array<ArrayConfig>;
  public tables: Array<TableConfig>;
  public buttons: Array<ButtonConfig>;
  public initDataFun: any; // 数据处理回调 config：配置，dataModels：数据，that：当前对象
  public searchFun?: any; // formInfo：提交数据对象,component:当前配置
  public breadcrumb?: BreadcrumbConfig;
  public paging?: PagingConfig;
  public sort?: SortConfig;
  public frontSort?: boolean; // 是否使用前端排序
  public frontPaging?: boolean; // 是否使用前端分页
  public openPaging?: boolean; // 打开分页
  public openTable?: boolean; // 打开表格
  public openFind?: boolean; // 打开查询
  public openButton?: boolean; // 打开按钮
  public openLabel?: boolean; // 打开label
}
